const WebSocket = require('ws');
const ClientService = require('./ClientService');
const MessageService = require('./MessageService');
const FileService = require('./FileService');

class ChatService {
  constructor(wss) {
    this.wss = wss;
    this.clientService = new ClientService(this);
    this.messageService = new MessageService(this);
    this.fileService = new FileService(this);

    this.init();
  }

  async init() {
    await this.messageService.loadHistory();
    this.setupWebSocketServer();
  }

  setupWebSocketServer() {
    this.wss.on('connection', async (ws, req) => {
      const clientId = this.clientService.registerClient(ws, req);

      // 发送初始数据
      this.messageService.sendWelcomeMessages(ws, clientId);
      this.messageService.sendHistory(ws);

      // 设置事件监听
      ws.on('message', (message, isBinary) => {
        if (isBinary) {
          this.fileService.handleFileChunk(clientId, message);
        } else {
          this.handleMessage(clientId, message);
        }
      });

      ws.on('close', () => this.handleClientDisconnect(clientId));
    });
  }

  handleMessage(clientId, message) {
    try {
      const data = JSON.parse(message.toString());
      const client = this.clientService.getClient(clientId);

      if (!client) return;

      switch (data.type) {
        case 'setNickname':
          this.clientService.handleSetNickname(clientId, data.nickname);
          if (!client.nickname) {
            this.messageService.sendHistory(client.ws);
          }
          break;
        case 'message':
          this.messageService.handleChatMessage(clientId, data.message);
          break;
        case 'image':
          this.fileService.handleImageMessage(clientId, data);
          break;
        case 'fileStart':
          this.fileService.initializeFileUpload(clientId, data);
          break;
        case 'fileEnd':
          this.fileService.finalizeFileUpload(clientId);
          break;
      }
    } catch (error) {
      console.error('消息处理错误:', error);
    }
  }

  handleClientDisconnect(clientId) {
    this.fileService.cleanupFileUpload(clientId);
    this.clientService.handleClientDisconnect(clientId);
  }

  broadcast(message) {
    const data = JSON.stringify(message);
    this.wss.clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data);
      }
    });
  }

  sendSystemMessage(ws, message) {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({
        type: 'system',
        message: message
      }));
    }
  }

  broadcastSystemMessage(message) {
    this.broadcast({
      type: 'system',
      message: message
    });
  }
}

module.exports = ChatService;